package com.zhaokuner.springboot.zk;

import com.alibaba.fastjson.JSONArray;
import com.zhaokuner.springboot.model.AfterRunnerModel;
import com.zhaokuner.springboot.refresh.RefreshAfterRunner;
import lombok.Data;
import lombok.extern.log4j.Log4j2;
import org.apache.zookeeper.CreateMode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

/**
 * <p>
 * Description:zk refresh log
 * <p>
 * Copyright: 2018-现在 北京掌通未来科技有限公司
 * <p>
 *
 * @author 赵希坤 zhaoxikun
 * @date 2020/8/1 16:49
 */
@Data
@Log4j2
public class ZkRefreshLog implements RefreshAfterRunner.Runner, EnvironmentAware {

    @Value("${spring.cloud.config.zkRefreshLog.prefix}")
    private String prefix;
    @Value("${spring.application.name}")
    private String applicationName;
    @Autowired
    private CuratorClientRefreshLaunch refreshLaunch;

    private Environment environment;

    private String flag;

    private String currentPath;

    private String port() {
        if (null != environment) {
            String port = environment.getProperty("server.port");
            if (null != port && !port.isEmpty()) {
                return port;
            }
        }
        return "port" + String.valueOf(ThreadLocalRandom.current().nextInt(1000, 10000));
    }

    private String ip() {
        String ip = null;
        try {
            ip = InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            log.error(e);
        }
        if (null == ip || ip.isEmpty()) {
            ip = "ip" + ThreadLocalRandom.current().nextInt(1000, 10000);
        }
        return ip;
    }

    private String flag() {
        if (null == flag) {
            return ip() + ":" + port();
        }
        return flag;
    }

    @Override
    public synchronized void run(AfterRunnerModel model) {
        try {
            JSONArray list = JSONArray.parseArray(model.getMsg());
            currentPath = "/" + prefix + "/" + applicationName + "/" + list.getString(0) + " " + list.getString(1);
            refreshLaunch.getClient().create().orSetData().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(currentPath + "/" + model.getResult() + "~" + flag());
            List<String> children = refreshLaunch.getClient().getChildren().forPath("/" + prefix + "/" + applicationName);
            if (!children.isEmpty()) {
                //删除上一次的
                for (String child : children) {
                    if (!currentPath.endsWith(child)) {
                        refreshLaunch.getClient().delete().deletingChildrenIfNeeded().forPath("/" + prefix + "/" + applicationName + "/" + child);
                    }
                }
            }
        } catch (Exception e) {
            log.error(e);
        }
    }


    @Override
    public HashMap<String, Object> map() throws Exception {
        HashMap<String, Object> map = new HashMap<>(8);
        String path = currentPath;
        if (null == path || path.isEmpty()) {
            path = "/" + prefix + "/" + applicationName;
            List<String> children = refreshLaunch.getClient().getChildren().forPath(path);
            if (null != children && !children.isEmpty()) {
                HashMap<String, Object> mmm = new HashMap<>(8);
                for (String child : children) {
                    String ppp = path + "/" + child;
                    mmm.put(ppp, refreshLaunch.getClient().getChildren().forPath(ppp));
                }
                map.put(path, mmm);
            }
        } else {
            List<String> children = refreshLaunch.getClient().getChildren().forPath(path);
            map.put(currentPath, children);
        }
        return map;
    }

    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }
}
